public class JoinTest2 {

	public static void main(String[] args) {
		Thread t1 = new Thread(new MyRunnable(10000), "t1");
		Thread t2 = new Thread(new MyRunnable(5000), "t2");
		Thread t3 = new Thread(new MyRunnable(1000), "t3");

		t1.start();
		t2.start();
		t3.start();

		// start second thread after waiting for 2 seconds or if it's dead
		try {
			t3.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		// start third thread only when first thread is dead
		try {
			t2.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		// let all threads finish execution before finishing main thread
		try {

			t1.join();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		System.out.println("All threads are dead, exiting main thread");
	}

}

class MyRunnable implements Runnable {

	int sure;

	public MyRunnable(int sure) {
		this.sure = sure;
	}

	@Override
	public void run() {
		System.out.println("Thread started:::" + Thread.currentThread().getName());
		try {
			Thread.sleep(sure);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("Thread ended:::" + Thread.currentThread().getName());
	}

}